package org.NooLab.itexx.app.gui.handlers;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Observable;

import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;

import org.NooLab.itexx.ITexxWindowCommons;
import org.NooLab.itexx.app.gui.JBusyLabel;
import org.NooLab.itexx.app.gui.definition.ITexxWindowGui2;
import org.NooLab.utilities.logging.PrintLog;
import org.NooLab.utilities.resources.ResourceLoader;
import org.apache.commons.collections.BidiMap;
import org.apache.commons.collections.bidimap.DualHashBidiMap;



public class MainStatusBar extends Observable{

	
	ITexxWindowGui2 windowGui;
	ITexxWindowCommons appCommons;
	
	JPanel statusbarPanel;
	JPanel PanelButtonHost,PanelWaitButtonHost ;
	
	StatusBarButtons statusBarButtons ;
	String iconImgResourceHome;
	
	BidiMap actionIndex = new DualHashBidiMap();
	Map<Integer,String> actionText = new HashMap<Integer,String>();
	
	PrintLog out;
	private int lastActivePosition=0;
	private int insertedPixelSpace=0 ;
	private JBusyLabel busyImg;
	JButton waitButton ,stoppingButton;
	private ButtonMover mover;
	private boolean isVisible=true;
	private boolean statusBarOnTop = false;
	
	// ========================================================================
	public MainStatusBar(ITexxWindowGui2 gui) {
	
		this.windowGui = gui;
		appCommons = windowGui .getAppCommons() ;
		out = appCommons.out;
		
		statusbarPanel = windowGui.getJPanelMainStatusBar() ;
		statusBarButtons = new StatusBarButtons(this);
		
		mover = new ButtonMover(this);
		iconImgResourceHome = "org/NooLab/itexx/resources/icons/"; // with trailing slash !
		if (appCommons.getAppProperties().getIniPreferences().isBlueButtons()){
			iconImgResourceHome = iconImgResourceHome + "blue/";	
		}
		if (appCommons.getAppProperties().getIniPreferences().isButtonsOnTop()){
			statusBarOnTop  = true;
		}
		if (appCommons.getAppProperties().getIniPreferences().isSmallButtons()){
			iconImgResourceHome = iconImgResourceHome + "small/";	
		}

	}
	// ========================================================================
	
	
	public void createButtons(int mode) {
		// 
		
		try {
		
			/*
			busyImg = createBusyIndicator();
			if (busyImg!=null){
				// put it on a button instead!
				// busyImg.setText("wait...");
				statusbarPanel.add(busyImg, BorderLayout.WEST) ;
				busyImg.setVisible(true);
			}
			*/
			
			
			PanelButtonHost = new JPanel();
			PanelButtonHost.setLayout(null);
			
			int w = statusbarPanel.getWidth();
			if (w<windowGui.getTopPanel().getWidth())w=windowGui.getTopPanel().getWidth();
			if (w<350)w=350;
			Dimension d = new Dimension(w,31);
			
			PanelButtonHost.setPreferredSize(d);
			PanelButtonHost.setSize(d);
			PanelButtonHost.setMinimumSize(d);
			statusbarPanel.add(PanelButtonHost, BorderLayout.EAST);
			
			PanelButtonHost.setVisible(true);
			PanelButtonHost.setBackground( new Color(0.90f,0.91f,0.96f,0.0f)) ;
			// we populate from right to left
			// see: D:/dev/java/icons/itexxx_icons/used
		
			
			PanelWaitButtonHost = new JPanel();
			PanelWaitButtonHost.setLayout(null);
			d = new Dimension(80,31);
			PanelWaitButtonHost.setMinimumSize(d);
			PanelWaitButtonHost.setSize(d);
			PanelWaitButtonHost.setPreferredSize(d);
			PanelWaitButtonHost.setVisible(true);
			PanelWaitButtonHost.setBackground( new Color(0.90f,0.91f,0.96f,0.0f)) ;
			
			statusbarPanel.add(PanelWaitButtonHost, BorderLayout.WEST);
			
			
			JButton  sbj ;
			
			
			sbj = createButton( null, 90, "wait", "WaitInfo.png",1 ,0);
			sbj.setVisible(false);
			waitButton = sbj;
			addMapItem(sbj, 0 ,"wait"); // onclick: stop all current processes
			PanelWaitButtonHost.add(waitButton);
			
			sbj = createButton( null, 90, "exiting", "Stop.png",1 ,0);
			sbj.setVisible(false);
			stoppingButton = sbj;
			addMapItem(sbj, 0 ,"please wait, application is stopping..."); // onclick: stop all current processes
			PanelWaitButtonHost.add(stoppingButton);

			
			int bix = 0;
			
			sbj = createButton( PanelButtonHost, bix, "exit (Ctrl-x, Alt-F4)", "Standby.png",1,13 );
			addMapItem(sbj, 99, "exit") ; bix++;

			
			sbj = createButton( PanelButtonHost, bix, "preferences", "Gear.png",1 ,4);
			addMapItem(sbj, 2 ,"preferences");bix++;
			sbj = createButton( PanelButtonHost, bix, "get help", "Question.png",1 ,1);
			addMapItem(sbj, 0 ,"Info");bix++;
			
			
			sbj = createButton( PanelButtonHost, bix, "clear results list (alt-c)", "Trash.png" ,1,8); 
			addMapItem(sbj, -3, "clear") ;bix++;
			
			sbj = createButton( PanelButtonHost, bix, "toggle perspective (alt-w)", "WindowDecorated.png",1 ,8); 
			addMapItem(sbj, 10, "fullwindow") ;bix++;
			
			/*
			sbj = createButton( PanelButtonHost, bix, "show graphics panel (alt-g)", "??" ,-1,0);
			addMapItem(sbj, 11, "simplewindow") ;bix++;
			*/
			
			sbj = createButton( PanelButtonHost, bix, "click to make it unresponsive", "PlayerPause.png" ,1,1);
			addMapItem(sbj, 15, "pause") ;bix++;
			
			sbj = createButton( PanelButtonHost, bix, "click to re-activate", "PlayerPlay.png" ,-1,-1);
			addMapItem(sbj, 16, "reactivate") ;bix++;
			
			
			sbj = createButton( PanelButtonHost, bix, "search in results (alt-s)", "Search.png",1,4 );
			addMapItem(sbj, 20, "search") ;bix++;
			
			
			/*
			sbj = createButton( PanelButtonHost, bix, "display source of selected item (alt-d)", "ZoomIn.png",1 ,10);
			addMapItem(sbj, 25, "displaysource") ;bix++;
			*/
			

			
			
		
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	

	
	private void addMapItem(JButton sbj, int aindex, String itext) {
		
		actionIndex.put(sbj, aindex) ; 
		actionText.put(aindex, itext);
		
	}
	
	private void insertSpace(int pixelcount) {
		// 
		insertedPixelSpace = pixelcount; 
	}


	private JButton createButton( JPanel buttonHost, int index, String tooltipStr, 
								  String imgFilename, int visible, int addSpace ) throws IOException {
		
		JButton _button =null;
		int w =5;
		
		if(addSpace>=0){
			insertSpace(addSpace);
		}
		
		if (w>tooltipStr.length())w=tooltipStr.length() ;
		
		String str = tooltipStr.substring(0,w) ;
		
		if(_button == null) {
			_button = new JButton();
			
			_button.setCursor(new Cursor(Cursor.HAND_CURSOR));
			
			if (buttonHost!=null){
				w = buttonHost.getWidth();
				if (w<80){
					w = 280;
				}
				
				if (index==0){
					lastActivePosition = w- 36 - insertedPixelSpace;
				}else{
					if (index>0){
						if (addSpace>=0){
							lastActivePosition = lastActivePosition - 31 - insertedPixelSpace;
						}
						
					}
					// else we draw onto the same position for a toggling effect
				}
			}else{
				lastActivePosition = 12;
			}
			
			
			_button.setLocation( lastActivePosition, 1);
			
			// out.print(2, "button index <"+index+"> , position = "+lastActivePosition);
			_button.setName("SBarButton_"+index);

			Dimension d = new Dimension(27, 28);
			_button.setSize(d);
			_button.setPreferredSize(d);
			_button.setMaximumSize( d);
			_button.setMinimumSize( d);

			_button.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
			_button.setOpaque(false) ;
			
			_button.setToolTipText(tooltipStr);
			
			String binpath = appCommons.getAppProperties().getOwnBinPath() ;
			
			try{

				ResourceLoader rL =  new ResourceLoader();
				rL.loadImageResource( windowGui.getClass(), iconImgResourceHome +imgFilename ) ;
				
				BufferedImage img = rL.getImageResource() ;
				_button.setIcon(new ImageIcon(img));

			}catch(Exception e){
				out.printErr(1, "Problem encountered while creating a button: internal resource not found, expected : "+(iconImgResourceHome +imgFilename)) ;
				out.printErr(1, e.getMessage()) ;
			}
			
			if (visible>=1){
				_button.setVisible(true);
			}else{
				_button.setVisible(false);
			}
			
			if (buttonHost!=null){
				buttonHost.add(_button);
			}
			
			insertedPixelSpace =0;
			
			_button.addMouseListener(new MouseAdapter() {
				public void mouseClicked(MouseEvent evt) {
					_button_MouseClicked(evt);
				}
			});
		}
		return _button;
	}
	
	
	protected void _button_MouseClicked(MouseEvent evt) {
		
		// out.print(2, "statusbar, Button clicked : "+evt);
		
		Component c= evt.getComponent();
		
		out.print(4, "statusbar, click to Button  "+c.getName());
		
		String atext ="";
		int aix = getActionIndex( c );
		if (actionText.containsKey(aix)){
			atext = actionText.get(aix);
		}

		int lastActivePanelix = appCommons.getModelController().getLastClickedPhysicalPanel() ;
		if ((aix==99) && (evt.isControlDown())){
			aix=97;
		}
		if (aix>=96){
			windowGui.getMainStatusBar().showStoppingIndicator(true);
			setChanged();
			this.notifyObservers( aix );
		}
		if ((aix==15) || (aix==16)){
			
			JButton sbj ;
			if (aix==15){
				sbj = (JButton)getActionComponent(15); sbj.setVisible(false);
				sbj = (JButton)getActionComponent(16); sbj.setVisible(true);
				
			}
			if (aix==16){
				sbj = (JButton)getActionComponent(16); sbj.setVisible(false);
				sbj = (JButton)getActionComponent(15); sbj.setVisible(true);
				
 			}
		}
		
		if (aix>-999){
			new StatusBarButtonHandler( windowGui, aix , atext, lastActivePanelix);
		}
	}

	private Component getActionComponent(int index){
		Component c=null;
		
		if (actionIndex.containsValue(index)){
			c = (Component) actionIndex.getKey(index);
		}
		
		return c;
	}
	
	private int getActionIndex(Component c) {

		int aix = -999;
		
		if (actionIndex.containsKey(c)){
			aix = (Integer) actionIndex.get(c);
		}
		return aix;
	}


	private JBusyLabel createBusyIndicator() {

		// we have to show the indicator on an empty button
		/*
			JBusyLabel busyIndicator ;

		// loading from resource does not work it is not animated...
        URL url = new URL("<URL to your Animated GIF>");
        Icon icon = new ImageIcon(url);
        JLabel label = new JLabel(icon);
        */

		JBusyLabel busyIndicator = null;
	    URL url;
	    
		try {
			
			// url = new URL("org/NooLab/itexx/resources/icons/animation/indicator.white.gif");
			
			/*
			ResourceLoader rL = new ResourceLoader();
			boolean hb = rL.loadImageResource(getClass(), "org/NooLab/itexx/resources/icons/animation/indicator.white.gif");
			
			
			if (hb){
				Image img = rL.getImageResource();
				Icon icon = new ImageIcon(img );
				busyIndicator = new JBusyLabel(icon);
				busyIndicator.setVisible(false);
				busyIndicator.setOpaque(false) ;
			}

			*/
			
			Icon icon =null;
	        // url = new URL("file://org/NooLab/itexx/resources/icons/animation/indicator.white.gif");
	        url = new URL("file://D:/data/iTexx/bin/resources/indicator.white.gif");
	        // Icon icon = new ImageIcon(url);
	        // JLabel label = new JLabel(icon);
	        if (icon!=null){
	        	busyIndicator = new JBusyLabel(icon);
	        }else{
	        	busyIndicator = new JBusyLabel(null);
	        	busyIndicator.setText("wait...") ;
	        }
			
	        
	        
		} catch (Exception e) {
			e.printStackTrace();
			busyIndicator = (JBusyLabel) new JLabel();
			busyIndicator.setText("wait...") ;
		}
		return busyIndicator;
	}
	
	
	class UpdateSpecialButtonView implements Runnable{
		
		Thread shbThrd;
		public UpdateSpecialButtonView(){
			shbThrd = new Thread(this, "shbThrd");
			shbThrd.start();
		}

		@Override
		public void run() {
			
			showButton();
		}
		
	}
	
	protected void showButton(){
		//windowGui.getAppCommons().getApp().getMainFrame().setSize( new Dimension(windowGui.getTopPanel().getWidth(),150));
		waitButton.setLocation(12,1) ;
		waitButton.setVisible(true) ;
		statusbarPanel.repaint() ;
		statusbarPanel.setVisible(true) ;
		statusbarPanel.setOpaque(true) ;
		mover.start(waitButton);
		/*
		stoppingButton.setLocation(12,1);
		stoppingButton.setVisible(true);
		stoppingButton.repaint();
		 */
		
	}
	
	public void showStoppingIndicator(boolean flag) {
		
		new UpdateSpecialButtonView();
		
		// showBusyIndicator(true);
		// showButton();
		/*
		mover.stop();
		waitButton.setVisible(false) ;
		PanelWaitButtonHost.remove(waitButton);
		stoppingButton.setVisible(true);
		
		int x=stoppingButton.getLocation().x;
		x=x+1-1;
		*/
	}
	
	public void showBusyIndicator(boolean flag) {
		//
		
		if (waitButton==null){
			return;
		}

		// busyImg.setVisible(flag) ;
		waitButton.setLocation(12,1);
		waitButton.setVisible(flag) ;

		if (flag){
			mover.start(waitButton);
		}else{
			mover.stop();
		}
		
	}


	public boolean isVisible() {
		return isVisible;
	}

	public void setVisible(boolean flag) {
		this.isVisible = flag;
		statusbarPanel.setVisible(isVisible);
	}

	
	
}


class ButtonMover implements Runnable{
	
	JButton button;
	Thread movThrd;
	boolean isRunning;
	MainStatusBar parent;
	
	
	public ButtonMover(MainStatusBar parent) {
		// 
		this.parent = parent;
		
	}

	public void start(JButton button){
		isRunning = false;
		this.button = button;
		PrintLog.Delay(5);
		
		try{

			movThrd = new Thread(this,"movThrd");
			movThrd.setPriority(10) ;
			movThrd.start();
			
		}catch(Exception e){
			
		}
	}
	
	public void stop(){
		isRunning=false;
	}

	@Override
	public void run() {
		
		isRunning = true;
		int dd=0, d=1;
		
		while ((isRunning) || (button.isVisible()==false)){
			
			parent.out.delay(45);
			dd=dd+d; 
			button.setLocation( button.getLocation().x + d, button.getLocation().y);
			if (dd>=20){
				d=-1; 
			}
			if (dd<=0){
				d = 1;
			}
			button.repaint();
		}
		
		isRunning = false;
	}
	
	 
	
}

class StatusBarButtons{
	
	ArrayList<StatusBarButton> items = new ArrayList<StatusBarButton>();
	
	
	public StatusBarButtons(MainStatusBar mainStatusBar) {
		// 
		
	}

	
	
}


class StatusBarButton{
	
	MainStatusBar statusBar;
	
	public StatusBarButton(MainStatusBar sb) {
		// 
		statusBar = sb;
	}
	
	
}

